package com.harmony.pilot.data.service;

import com.harmony.pilot.common.dto.CodeContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;

/**
 * OpenHarmony代码专用分析器
 * 专门处理ohcode目录下的OpenHarmony子系统代码
 */
@Slf4j
@Service
public class OpenHarmonyAnalyzer {
    
    private static final String OH_CODE_DIR = "ohcode";
    
    // OpenHarmony常用命名空间
    private static final List<String> OH_NAMESPACES = List.of(
        "OHOS", "AAFwk", "AppExecFwk", "Media", "Notification",
        "FileManagement", "Graphics", "Rosen", "DistributedHardware"
    );
    
    /**
     * 分析OpenHarmony项目结构
     */
    public Map<String, Object> analyzeOHProject(String projectRoot) {
        log.info("Analyzing OpenHarmony project: {}", projectRoot);
        
        Map<String, Object> analysis = new HashMap<>();
        
        try {
            File ohCodeDir = new File(projectRoot, OH_CODE_DIR);
            if (!ohCodeDir.exists()) {
                log.warn("ohcode directory not found in: {}", projectRoot);
                analysis.put("found", false);
                return analysis;
            }
            
            analysis.put("found", true);
            
            // 查找子系统
            List<Map<String, Object>> subsystems = new ArrayList<>();
            File[] subdirs = ohCodeDir.listFiles(File::isDirectory);
            
            if (subdirs != null) {
                for (File subdir : subdirs) {
                    Map<String, Object> subsystemInfo = analyzeSubsystem(subdir);
                    subsystems.add(subsystemInfo);
                }
            }
            
            analysis.put("subsystems", subsystems);
            analysis.put("totalSubsystems", subsystems.size());
            
        } catch (Exception e) {
            log.error("Failed to analyze OpenHarmony project", e);
            analysis.put("error", e.getMessage());
        }
        
        return analysis;
    }
    
    /**
     * 分析子系统
     */
    private Map<String, Object> analyzeSubsystem(File subsystemDir) {
        Map<String, Object> info = new HashMap<>();
        info.put("name", subsystemDir.getName());
        info.put("path", subsystemDir.getAbsolutePath());
        
        try {
            // 查找bundle.json
            File bundleJson = new File(subsystemDir, "bundle.json");
            if (bundleJson.exists()) {
                info.put("hasBundleJson", true);
            }
            
            // 统计文件类型
            Map<String, Integer> fileStats = countFileTypes(subsystemDir);
            info.put("fileStats", fileStats);
            
            // 查找GN构建文件
            List<String> gnFiles = findGnFiles(subsystemDir);
            info.put("gnFiles", gnFiles);
            info.put("gnFileCount", gnFiles.size());
            
            // 提取模块信息
            List<String> modules = extractModules(subsystemDir);
            info.put("modules", modules);
            
        } catch (Exception e) {
            log.error("Failed to analyze subsystem: {}", subsystemDir.getName(), e);
            info.put("error", e.getMessage());
        }
        
        return info;
    }
    
    /**
     * 统计文件类型
     */
    private Map<String, Integer> countFileTypes(File dir) {
        Map<String, Integer> stats = new HashMap<>();
        
        try (Stream<Path> paths = Files.walk(dir.toPath())) {
            paths.filter(Files::isRegularFile)
                 .forEach(path -> {
                     String fileName = path.getFileName().toString();
                     String ext = getFileExtension(fileName);
                     stats.merge(ext, 1, Integer::sum);
                 });
        } catch (IOException e) {
            log.error("Failed to count file types", e);
        }
        
        return stats;
    }
    
    /**
     * 查找所有GN文件
     */
    private List<String> findGnFiles(File dir) {
        List<String> gnFiles = new ArrayList<>();
        
        try (Stream<Path> paths = Files.walk(dir.toPath())) {
            paths.filter(Files::isRegularFile)
                 .filter(path -> path.getFileName().toString().endsWith(".gn"))
                 .forEach(path -> gnFiles.add(path.toString()));
        } catch (IOException e) {
            log.error("Failed to find GN files", e);
        }
        
        return gnFiles;
    }
    
    /**
     * 提取模块列表
     */
    private List<String> extractModules(File subsystemDir) {
        Set<String> modules = new HashSet<>();
        
        // 从BUILD.gn中提取模块
        File buildGn = new File(subsystemDir, "BUILD.gn");
        if (buildGn.exists()) {
            try {
                String content = Files.readString(buildGn.toPath());
                Pattern pattern = Pattern.compile("\\w+\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)");
                Matcher matcher = pattern.matcher(content);
                
                while (matcher.find()) {
                    modules.add(matcher.group(1));
                }
            } catch (IOException e) {
                log.error("Failed to read BUILD.gn", e);
            }
        }
        
        return new ArrayList<>(modules);
    }
    
    /**
     * 获取文件扩展名
     */
    private String getFileExtension(String fileName) {
        int lastDot = fileName.lastIndexOf('.');
        if (lastDot > 0 && lastDot < fileName.length() - 1) {
            return fileName.substring(lastDot + 1);
        }
        return "unknown";
    }
    
    /**
     * 查找相关的OpenHarmony API
     */
    public List<String> findRelatedOHAPIs(CodeContext context) {
        List<String> apis = new ArrayList<>();
        
        String code = context.getCode();
        if (code == null) {
            return apis;
        }
        
        // 查找命名空间使用
        for (String namespace : OH_NAMESPACES) {
            if (code.contains(namespace + "::")) {
                apis.add(namespace);
            }
        }
        
        // 查找常用的OpenHarmony API
        if (code.contains("AbilityContext")) apis.add("AbilityContext");
        if (code.contains("Want")) apis.add("Want");
        if (code.contains("BundleInfo")) apis.add("BundleInfo");
        if (code.contains("HiLog")) apis.add("HiLog");
        if (code.contains("NativeRdb")) apis.add("NativeRdb");
        
        return apis;
    }
    
    /**
     * 检测是否为OpenHarmony代码
     */
    public boolean isOpenHarmonyCode(String filePath, String code) {
        if (filePath != null && filePath.contains(OH_CODE_DIR)) {
            return true;
        }
        
        if (code == null) {
            return false;
        }
        
        // 检测OpenHarmony特征
        return OH_NAMESPACES.stream().anyMatch(code::contains) ||
               code.contains("bundle.json") ||
               code.contains("module.json") ||
               code.contains("ohos_") ||
               code.contains("OH_");
    }
    
    /**
     * 获取OpenHarmony编码建议
     */
    public List<String> getCodingGuidelines() {
        return List.of(
            "使用OHOS命名空间",
            "遵循OpenHarmony编码规范",
            "使用HiLog进行日志记录",
            "正确处理Ability生命周期",
            "使用统一的错误码体系",
            "注意权限管理",
            "使用分布式能力要添加相应权限"
        );
    }
    
    /**
     * 分析特定子系统（文件管理）
     */
    public Map<String, Object> analyzeFileManagementSubsystem(String projectRoot) {
        Map<String, Object> analysis = new HashMap<>();
        
        String subsystemPath = Paths.get(projectRoot, OH_CODE_DIR, 
            "filemanagement_user_file_service").toString();
        
        File subsystemDir = new File(subsystemPath);
        if (!subsystemDir.exists()) {
            analysis.put("found", false);
            return analysis;
        }
        
        analysis.put("found", true);
        analysis.put("name", "File Management Service");
        analysis.put("description", "OpenHarmony文件管理服务子系统");
        
        // 分析关键目录
        analysis.put("hasFrameworks", new File(subsystemDir, "frameworks").exists());
        analysis.put("hasInterfaces", new File(subsystemDir, "interfaces").exists());
        analysis.put("hasServices", new File(subsystemDir, "services").exists());
        analysis.put("hasTest", new File(subsystemDir, "test").exists());
        
        return analysis;
    }
    
    /**
     * 分析特定子系统（图形2D）
     */
    public Map<String, Object> analyzeGraphic2DSubsystem(String projectRoot) {
        Map<String, Object> analysis = new HashMap<>();
        
        String subsystemPath = Paths.get(projectRoot, OH_CODE_DIR, 
            "graphic_graphic_2d").toString();
        
        File subsystemDir = new File(subsystemPath);
        if (!subsystemDir.exists()) {
            analysis.put("found", false);
            return analysis;
        }
        
        analysis.put("found", true);
        analysis.put("name", "Graphic 2D");
        analysis.put("description", "OpenHarmony 2D图形渲染子系统");
        
        // 分析Rosen引擎
        analysis.put("hasRosen", new File(subsystemDir, "rosen").exists());
        analysis.put("hasFrameworks", new File(subsystemDir, "frameworks").exists());
        analysis.put("hasInterfaces", new File(subsystemDir, "interfaces").exists());
        
        return analysis;
    }
}

